package com.lost.octopus.es.helper.service;

import com.lost.octopus.es.helper.entity.model.QueryBuilder;
import com.lost.octopus.es.helper.entity.query.QueryResult;
import com.lost.octopus.es.helper.annotation.EsDocument;
import com.lost.octopus.es.helper.constant.IndexSettingEnum;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.aggregations.Aggregations;
import org.springframework.data.elasticsearch.annotations.Document;

import java.io.IOException;
import java.util.Map;

import lombok.NonNull;

/**
 * 注解es查询服务
 * 基于{@link EsDocument} 注解的es查询服务
 * @author zhangbh
 **/
public interface DocumentEsService extends EsService{

    /**
     * 删除索引
     * @param clazz 类型，需要有注解 {@link EsDocument}
     * @return 操作成功索引数
     */
    int deleteIndex(Class<?> clazz);

    /**
     * 重置索引，比清空效率高
     * @param clazz 注解了Document的对象 {@link Document}，如果为空不创建Mapping
     * @return 真实名称
     */
    boolean reCreateIndex(Class<?> clazz);

    /**
     * 设置分页查询最大数量
     * @param clazz  类型，需要有注解 {@link EsDocument}
     * @param maxResult 最大数量
     * @return 操作成功索引数
     */
    int setMaxResultWindow(@NonNull Class<?> clazz, Integer maxResult);

    /**
     * 手动配置索引
     * @param clazz  类型，需要有注解 {@link EsDocument}
     * @param settings 配置map,key见 {@link IndexSettingEnum}
     * @return 操作成功索引数
     */
    int indexSetting(@NonNull Class<?> clazz, @NonNull Map<String, Object> settings);

    /**
     * 查询，可以使用 getBoolQueryBuilder + getSort自定义查询
     * 场景，当注解功能无法实现时使用
     * @param search 查询对象
     * @param clazz 转换实体
     * @return 查询结果
     * @throws IOException 异常
     */
    <T> QueryResult<T> boolSearch(QueryBuilder search, Class<T> clazz) throws IOException;

    /**
     * 查询，可以使用 getBoolQueryBuilder + getSort自定义查询
     * 场景，当注解功能无法实现时使用
     * @param search 查询对象
     * @return 查询结果
     * @throws IOException 异常
     */
    QueryResult<Map<String, Object>> boolSearch(QueryBuilder search) throws IOException;

    /**
     * 查询分组聚合，配合 {@link EsDocument#aggregationStrategy()}
     * @param search 查询条件，可以不传分页
     * @return 分组结果
     * @throws IOException 异常
     */
    Aggregations boolSearchAgg(QueryBuilder search) throws IOException;

    /**
     * 获取原始的es返回对象 {@link SearchResponse}
     * @param search 查询构建对象
     * @return es返回对象
     * @throws IOException 异常
     */
    SearchResponse boolSearchGetResponse(QueryBuilder search) throws IOException;

}
